# --*-- coding=utf-8 --*--
"""
JSONPATH模块常用方法的封装
"""
import re
import jsonpath


def get_paths(jsonpath_str):
    """
    获取json_path系列路径，从根节点到子节点
    :param jsonpath_str:
    :return:
    """
    if not isinstance(jsonpath_str, str):
        return
    paths = []
    t = ''
    for i, ch in enumerate(jsonpath_str):
        if ch.isalpha():
            t += ch
        elif ch == '[':
            paths.append(t)
            t = ''
            t += ch
        elif ch == ']':
            t += ch
            paths.append(t)
            t = ''
        elif ch == '.':
            paths.append('.')
            t = ''
        elif ch.isdigit():
            t += ch
        if i == len(jsonpath_str) - 1 and ch.isalpha():
            paths.append(t)
    return paths


def set_value(dict_data, json_path, value):
    """
    通过jsonpath设置字典数据修改指定的值
    :param dict_data:
    :param json_path:
    :param value:要变更的值
    """
    if not isinstance(dict_data, dict):
        return
    paths = get_paths(json_path)
    data = dict_data
    for i, key in enumerate(paths):
        if isinstance(dict_data, dict) and key.isalpha():
            if i < len(paths) - 1:
                dict_data = dict_data[key]
            else:
                # 更新原有数据
                dict_data[key] = value
        elif isinstance(dict_data, list) and key.isalpha() is False:
            index = int(key[1:-1])
            dict_data = dict_data[index]
    # print(data)
    return data


def get_value(dict_data, json_path, pattern=None):
    """
    通过jsonpath字符串获取字典指定的值
    :param pattern: re表达式
    :param dict_data:字典类型的数据
    :param json_path:jsonpath字符串
    :return:
    """
    if not isinstance(dict_data, dict):
        return dict_data
    if not isinstance(json_path, str):
        return dict_data
    value = jsonpath.jsonpath(dict_data, '$.' + json_path)
    # print(value)
    if pattern is None:
        return value[0]
    else:
        # 一般过滤的格式如下：r'(?<=SEQNBR=)\w{10}'
        p = re.compile(pattern)
        value = re.search(p, value[0])
        return value[0]
